namespace Viyi.Util.Extensions;

/// <summary>
/// 包含一系列对<c>object</c>进行扩展的方法的类。
/// </summary>
public static partial class ObjectExtensions {
    /// <summary>如果 `predicate` 运算得到 `true`，则执行 `fn`</summary>
    /// <remarks>
    /// 不管是否执行 `fn`，都会返回该扩展方法的调用者。
    /// 该扩展方法是对 `Also` 扩展方法在具有分支条件情况下的简单封装。
    /// </remarks>
    public static T If<T>(this T me, Func<T, bool> predicate, Action<T> fn) {
        if (predicate(me)) { fn(me); }
        return me;
    }

    /// <summary>如果 `predicate` 运算得到 `false`，则执行 `fn`</summary>
    /// <remarks>
    /// 不管是否执行 `fn`，都会返回该扩展方法的调用者。
    /// 该扩展方法是对 `Also` 扩展方法在具有分支条件情况下的简单封装。
    /// </remarks>
    public static T IfNot<T>(this T me, Func<T, bool> predicate, Action<T> fn) {
        if (!predicate(me)) { fn(me); }
        return me;
    }

    /// <summary>如果调用者与 `expect` 等价，则执行 `fn`</summary>
    /// <remarks>
    /// 不管是否执行 `fn`，都会返回该扩展方法的调用者。
    /// 该扩展方法是对 `Also` 扩展方法在在对比特定值情况下的简单封装。
    /// </remarks>
    public static T If<T>(this T me, T expect, Action<T> fn) where T : IEquatable<T> =>
        me.If(it => expect == null ? it == null : it?.Equals(expect) == true, fn);

    /// <summary>如果调用者与 `expect` 不等，则执行 `fn`</summary>
    /// <remarks>
    /// 不管是否执行 `fn`，都会返回该扩展方法的调用者。
    /// 该扩展方法是对 `Also` 扩展方法在对比特定值情况下的简单封装。
    /// </remarks>
    public static T IfNot<T>(this T me, T expect, Action<T> fn) where T : IEquatable<T> =>
        me.IfNot(it => expect == null ? it == null : it?.Equals(expect) == true, fn);
}
